/* 二维数组：元素本身也是数组的一维数组 */

#include <stdio.h>

void PrintArray(int (*a)[3], int size)  // 二维数组作为参数被传递，参数的写法就是：int (*a)[3] 表示一个数组指针，它指向一个一维数组，3表示有3个int，int size表示有几个这样的数组
{
    for(int i = 0; i < size; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            printf("%d ", *(*(a + i) + j));
            // printf("%d", a + 1);  //跨过一个数组，表示下一行
            // printf("%d", *(a + 1));   //下一行数组的首元素地址
            // printf("%d", *(a + 1) + j); //第j个元素的地址
            // printf("%d", *(*(a + 1) + j));  //取第j个元素
            /* 公式：用指针去取一个二维数组元素，取第i行第j个元素的值
                    *(*(a + i) + j)
                    *(a[i] + j)
                    a[i][j]); */ 
            // 这几种写法没区别
        }
        printf("\n");
    }
}

int main()
{
#if 0
    //int a[10];  // 数组传的是元素类型的指针
    // 而二维数组的每个元素的类型还是数组，数组指针

    //二维数组初始化
    int a[2][3] = 
    {
        {1, 2, 3},
        {4, 5, 6}
    };

    for(int i = 0; i < 2; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            printf("%d %p\n", a[i][j], &a[i][j]);
        }
        printf("\n");
    }
#endif

#if 0
    int a[2][3] = 
    {
        {1, 2, 3},
        {4, 5, 6}
    };

    PrintArray(a,2);

    printf("%p %p %p\n", a, &a, &a[0][0]);
    printf("%p %p %p\n", a+1, &a+1, &a[0][0]+1);
    // a：数组指针（a 是二维数组 a 的首行地址，可以看作是一个指向整个二维数组的指针。）
    // &a：二维数组指针（&a 是整个二维数组 a 的地址，它指向整个二维数组的开头。）
    // &a[0][0]：元素指针（&a[0][0] 是数组中第一个元素的地址，即二维数组中第一行第一列元素的地址。）
    // 一个数组指针走一步跨一个一维数组
    // 一个二维数组指针走一步跨整个二维数组
    // 一个元素指针走一步跨一个元素
#endif

#if 0
    int a[2][3] = 
    {
        {1, 2, 3},
        {4, 5, 6}
    };

    int (*p)[3] = a;
    //int (*p)[2] = a;  // 把a的值给到一个指向两个int类型的数组指针 **(p+1)取出3，打印会报错
    //int *p = a;   //把a的值给到一个普通类型的指针
    //a充其量不过是一个数组指针的地址的值，它是一个值，可以把这个值给到任何一个数组指针，实际上最后这个指针会指在哪个位置全看这个指针p的类型
    printf("%d\n", **(p+1));    // *(p+1)第二行首元素地址，再取*就是取值 
#endif

#if 0
    int a[2][3] = 
    {
        {1, 2, 3},
        {4, 5, 6}
    };
    
    int (*p)[3] = a;
    printf("%d\n", p[0]);  //p[0]是地址，*(p[0])是值，同p[0][0]
    printf("%d\n", *(p[1] - 1));
    //a[i] = *(a + i)
    //a[j][j] = *(*(a + i) + j)
#endif

    return 0;
}